home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et-2_2.lha / et2.2 / src / TextFormatter.C < prev    next >
C/C++ Source or Header  |  1990-12-04  |  5KB  |  213 lines

  1. //$TextFormatter, SimpleFormatter, FoldingFormatter$
  2.  
  3. #include "TextFormatter.h"
  4. #include "StaticTView.h"
  5.   
  6. //---- TextFormatter ----------------------------------------------------------
  7.  
  8. AbstractMetaImpl(TextFormatter, (TP(tv), TB(isPreemptive), T(startedAt), 0));
  9.  
  10. TextFormatter::TextFormatter(StaticTextView *t)
  11. {
  12.     tv= t;
  13. }
  14.  
  15. int TextFormatter::DoIt(int , int , int )
  16. {
  17.     AbstractMethod("DoIt");
  18.     return 0;
  19. }
  20.  
  21. void TextFormatter::ResumeFormat(bool)
  22. {
  23.     AbstractMethod("ResumeFormat");
  24. }
  25.  
  26. //---- SimpleFormatter -----------------------------------------------------
  27.  
  28. MetaImpl0(SimpleFormatter);
  29.  
  30. SimpleFormatter::SimpleFormatter(StaticTextView *t) : TextFormatter(t)
  31. {
  32. }
  33.  
  34. int SimpleFormatter::DoIt(int fromLine, int upto, int minUpto)
  35. {
  36.     register int end, line, start= tv->StartLine(fromLine);
  37.     LineDesc ld, maxld;
  38.     Text *t= tv->GetText();
  39.     AutoTextIter next(t, start, upto);
  40.     line= startedAt= fromLine;
  41.     
  42.     tv->StartFormatting(); // ???
  43.     while ((end= next.Line(&ld)) != cEOT) {
  44.     maxld.Max(ld);
  45.     if (!tv->MarkLine(line,start,end,&maxld) && line >= minUpto) 
  46.         return (line-1);
  47.     line++;
  48.     start= end;
  49.     }
  50.     return line-1;
  51. }
  52.  
  53. void SimpleFormatter::ResumeFormat(bool preemptive)
  54. {
  55. }
  56.  
  57. //---- class FoldingFormatter -----------------------------------------------
  58.  
  59. const int cMaxFormat = 3;      // maximum number of consecutive lines formatted 
  60.                    // without interruption (if preemptive
  61.                    // formatting is enabled)
  62.  
  63. MetaImpl(FoldingFormatter, (T(width), TP(text), TB(wasPreempted), T(start),
  64.                 T(end), T(nWords), T(startLine), T(line), T(lastpeek),
  65.                 T(wx), T(cx), T(preemptedAt), 0));
  66.  
  67. FoldingFormatter::FoldingFormatter(StaticTextView *t) : TextFormatter(t)
  68. {
  69.     preemptedAt= -1;
  70. }
  71.  
  72. int FoldingFormatter::DoIt(int fromLine, int upto, int minUpto)
  73. {
  74.     int to;
  75.     
  76.     startedAt= max(0, fromLine-1);
  77.     tv->StartFormatting(); // ???
  78.     Mark before(tv->MarkAtLine(startedAt));
  79.     to= Format(startedAt, tv->StartLine(startedAt), upto, max(minUpto, fromLine));
  80.     Mark after(tv->MarkAtLine(startedAt));
  81.     
  82.     if (startedAt == fromLine-1 && !after.HasChanged(before.Pos(), before.Len()))
  83.     startedAt++; // no backward propagation
  84.     return to;
  85. }
  86.  
  87. int FoldingFormatter::Format(int fromLine, int fromCh, int upto, int minUpto)
  88. {
  89.     Text *t= tv->GetText();
  90.     AutoTextIter next(t, fromCh, upto);
  91.     text= t;
  92.     int ch;
  93.     width= tv->GetInnerExtent().x;
  94.     start= fromCh; 
  95.     nWords= wx= cx= 0;
  96.     line= startLine= lastpeek= fromLine;
  97.     LineDesc maxld, ld;
  98.     
  99.     while (TRUE) {            
  100.     // check whether formatting process should be preempted
  101.     if (isPreemptive  && tv->TestFlag(eTextFormPreempt) && Suspend(minUpto))
  102.         return line-1;
  103.     ch= next.Token(&wx,&ld);
  104.     // handle special case if one word has to be folded on several lines
  105.     if (cx + wx > width && nWords == 0) {
  106.         end= next.GetPos();
  107.         BreakWord (&maxld);
  108.         wx= 0;
  109.     }
  110.  
  111.     switch (ch) {
  112.     case cEOT: 
  113.         maxld.Max(ld);
  114.         tv->MarkLine(line, start, next.GetPos(), &maxld);
  115.         return line;
  116.  
  117.     case '\t':
  118.         wx = text->Tabulate(cx);  // ---> no break
  119.     case ' ': case '\n': case '\r':            
  120.         maxld.Max(ld);
  121.         if (ch == '\n' || ch == '\r' || (cx + wx > width)) {
  122.         end= next.GetPos();
  123.         if (!tv->MarkLine(line,start,end,&maxld) && line >= minUpto) 
  124.             return (line-1);
  125.         line++;
  126.         start= end;
  127.         cx= 0;
  128.         nWords= 0;
  129.         } else {
  130.         cx+= wx;
  131.         nWords++;
  132.         }
  133.         break;
  134.  
  135.     default:
  136.         if (cx + wx > width) {  // wordwrap
  137.         end= next.GetLastPos();
  138.         if (!tv->MarkLine(line,start,end,&maxld) && line >= minUpto)  // line did not change
  139.             return (line-1);
  140.         maxld= ld;
  141.         line++;
  142.         start= end;
  143.         nWords= 0;
  144.         cx= wx;
  145.         } else {
  146.         maxld.Max(ld);
  147.         cx+= wx;
  148.         nWords++;
  149.         }
  150.         break;
  151.     }
  152.     }
  153. }
  154.  
  155. void FoldingFormatter::BreakWord(LineDesc *maxld)
  156. {
  157.     int l= 0, w, cw= 0; 
  158.     AutoTextIter ti(text, start, end); // avoid nesting of nextc
  159.     LineDesc ld;
  160.  
  161.     maxld->Reset();
  162.     while (ti(&w,&ld) != cEOT) 
  163.     if (cw + w > width) {
  164.         cw= w;
  165.         end= ti.GetPos() - 1;
  166.         tv->MarkLine(line,start,end, maxld); 
  167.         *maxld= ld;
  168.         line++;
  169.         start= end;
  170.     } else {      
  171.         maxld->Max(ld);
  172.         cw+= w;
  173.     }
  174.     cx= cw;
  175.     end= ti.GetPos();
  176.  
  177. bool FoldingFormatter::Suspend(int minUpto)
  178. {
  179.     if (line > minUpto && line-lastpeek > cMaxFormat) {
  180.     lastpeek= line;
  181.     if (tv->SuspendFormatting()) {
  182.         if (preemptedAt != -1) 
  183.         preemptedAt= min(line, preemptedAt);
  184.         else 
  185.         preemptedAt= line;
  186.         wasPreempted= TRUE;
  187.         tv->MarkLineAsChanged(line);
  188.         return TRUE;
  189.     }        
  190.     }
  191.     return FALSE;
  192. }
  193.  
  194. void FoldingFormatter::ResumeFormat(bool preempt)
  195. {
  196.     register int i;
  197.  
  198.     if (preemptedAt == -1)
  199.     return;
  200.     isPreemptive= preempt;
  201.     wasPreempted= FALSE;
  202.     for (i= preemptedAt; i < tv->NumberOfLines(); i++)
  203.     if (tv->MarkAtLine(i)->state != eStateNone) {
  204.         tv->ChangedAt(i, 0, FALSE, i);
  205.         if (wasPreempted)
  206.         break;
  207.     }
  208.     isPreemptive= TRUE;
  209.     preemptedAt= wasPreempted ? i : -1;
  210. }
  211.  
  212.